package cn.jfast.expand.wx.api.core;

import cn.jfast.expand.wx.api.consts.WxApiUrl;
import cn.jfast.expand.wx.api.exception.WxRespException;
import cn.jfast.expand.wx.api.kit.HttpRequest;
import cn.jfast.expand.wx.api.msg.AuthInfo;
import cn.jfast.expand.wx.api.msg.MPAct;
import cn.jfast.expand.wx.api.msg.WebAuthInfo;
import cn.jfast.framework.log.LogFactory;
import cn.jfast.framework.log.LogType;
import cn.jfast.framework.log.Logger;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import java.io.IOException;

/**
 * 微信开放平台API接口设计
 */
public class WxOpenApiHandler implements WxOpenApi {

    private static final Logger log = LogFactory.getLogger(LogType.JFast,WxOpenApiHandler.class);

    private MPAct mpAct;

    private String ticket;
    
    public WxOpenApiHandler(String mpKey) {
    	this(mpKey,"");
    }
    /**
     * 微信开放平台接口构建
     * @param mpAct     服务组件公众号信息
     * @param ticket    允许凭证
     */
    public WxOpenApiHandler(String mpKey,String ticket) {
    	mpAct = MpActHolder.getMpAct(mpKey);
        this.ticket = ticket;
    }

    @Override
    public String getComponentToken() throws WxRespException {
        String token = mpAct.getAccessToken();
        if (null == token
                || token.isEmpty()
                || mpAct.getExpiresIn() < System.currentTimeMillis()) {
            synchronized (this){
                refreshComponentToken();
            }
            token = mpAct.getAccessToken();
        }
        return token;
    }

    @Override
    public void refreshComponentToken() throws WxRespException {
        String result = "";
        String data = "{" +
                "\"component_appid\":\"" + mpAct.getAppId() + "\"," +
                "\"component_appsecret\":\"" + mpAct.getAppSecert() + "\"," +
                "\"component_verify_ticket\":\"" + ticket + "\"" +
                "}";
        try {
            result = HttpRequest.post(WxApiUrl.COMPONENT_TOKEN_API,
                    HttpRequest.APPLICATION_JSON,
                    data);
        } catch (IOException e) {
            log.error("刷新服务组件ACCESS_TOKEN时出现异常!!!", e);
        }
        JSONObject jsonResult = JSON.parseObject(result);
        if (null != jsonResult.getInteger("errcode") && jsonResult.getInteger("errcode") != 0) {
            throw new WxRespException(result);
        }
        mpAct.createAccessToken(result);
    }

    @Override
    public void createPreauthcode() throws WxRespException {
        String url = String.format(WxApiUrl.COMPONENT_API,
                "api_create_preauthcode", getComponentToken());
        String result = "";
        String data = "{\"component_appid\":\"" + mpAct.getAppId() + "\"}";
        try {
            result = HttpRequest.post(url, HttpRequest.APPLICATION_JSON, data);
        } catch (IOException e) {
            log.error("创建公众权预授权码时出现异常!!!", e);
        }
        JSONObject jsonResult = JSON.parseObject(result);
        if (null != jsonResult.getInteger("errcode") && jsonResult.getInteger("errcode") != 0) {
            throw new WxRespException(result);
        }
        mpAct.createPreAuthCode(result);
    }

    @Override
    public String getPreauthcode() throws WxRespException {
        String auth_code = mpAct.getPreAuthCode();
        if (null == auth_code
                || mpAct.getPreAuthExpiresIn() < System.currentTimeMillis()){
            synchronized (this.mpAct){
                createPreauthcode();
            }
        }
        return auth_code;
    }

    @Override
    public AuthInfo queryAuth(String authCode) throws WxRespException {
        String url = String.format(WxApiUrl.COMPONENT_API, "api_query_auth", getComponentToken());
        String result = "";
        String data = "{" +
                "\"component_appid\":\"" + mpAct.getAppId() + "\" ," +
                "\" authorization_code\": \"" + authCode + "\"" +
                "}";
        try {
            result = HttpRequest.post(url, HttpRequest.APPLICATION_JSON, data);
        } catch (IOException e) {
            log.error("换取授权公众号信息时出现异常!!!", e);
        }
        JSONObject jsonResult = JSON.parseObject(result);
        if (null != jsonResult.getInteger("errcode") && jsonResult.getInteger("errcode") != 0) {
            throw new WxRespException(result);
        }
        AuthInfo tmp = JSON.parseObject(result, AuthInfo.class);
        return tmp;
    }

    @Override
    public String getAuthAccessToken(String authAppId, String authRefreshToken) throws WxRespException {
        throw new UnsupportedOperationException("暂不支持该功能");
    }

    @Override
    public void refreshAuthAccessToken(String authAppId, String authRefreshToken) throws WxRespException {
    	throw new UnsupportedOperationException("暂不支持该功能");
    }

    @Override
    public AuthInfo getAuthorizerInfo(String authAppId) throws WxRespException {
    	throw new UnsupportedOperationException("暂不支持该功能");
    }

    @Override
    public String getAuthorizerOption(String authAppId, String optionName) throws WxRespException {
        String url = String.format(WxApiUrl.COMPONENT_API, "api_get_authorizer_option", getComponentToken());
        String result = "";
        String data = "{" +
                "\"component_appid\":\""+mpAct.getAppId()+"\"," +
                "\"authorizer_appid\": \""+authAppId+"\"," +
                "\"option_name\": \""+optionName+"\"" +
                "}";
        try {
            result = HttpRequest.post(url, HttpRequest.APPLICATION_JSON, data);
        } catch (IOException e) {
            log.error("获取授权公众号[%s]的选项值时出现异常!!!",authAppId);
            log.error(e.getLocalizedMessage(), e);
        }
        JSONObject jsonResult = JSON.parseObject(result);
        if (null != jsonResult.getInteger("errcode") && jsonResult.getInteger("errcode") != 0) {
            throw new WxRespException(result);
        }
        JSONObject tmp = JSON.parseObject(result);
        String optionValue = tmp.getString("option_value");
        if (log.isInfoEnable()) {
            String info = "获取授权公众号["+authAppId+"]";
            if(info.equals("location_report")){
            	info += "地理位置上报选项成功,当前状态为: ";
            	if (optionValue.equals("0")) {
                    info += "无上报";
                } else if (optionValue.equals("1")) {
                    info += "进入会话时上报";
                } else {
                    info += "每5s上报";
                }
            } else if(info.equals("voice_recognize")){
            	info += "语音识别选项成功,当前状态为: ";
                info += (optionValue.equals("0")?"关闭":"开启");
            } else if(info.equals("voice_recognize")){
            	info += "多客服选项成功,当前状态为: ";
                info += (optionValue.equals("0")?"关闭":"开启");
            }        
            log.info("%s",info);
        }
        return result;
    }

    @Override
    public void setAuthorizerOption(String authAppId, String optionName, String optionValue) throws WxRespException {
        String url = String.format(WxApiUrl.COMPONENT_API, "api_set_authorizer_option", getComponentToken());
        String result = "";
        String data = "{" +
                "\"component_appid\":\""+mpAct.getAppId()+"\"," +
                "\"authorizer_appid\": \""+authAppId+"\"," +
                "\"option_name\": \""+optionName+"\"," +
                "\"option_value\":\""+optionValue+"\"" +
                "}";
        try {
            result = HttpRequest.post(url, HttpRequest.APPLICATION_JSON, data);
        } catch (IOException e) {
            log.error("设置授权公众号[%s]的选项值时出现异常!!!",authAppId);
            log.error(e.getLocalizedMessage(), e);
        }
        JSONObject jsonResult = JSON.parseObject(result);
        if (null != jsonResult.getInteger("errcode") && jsonResult.getInteger("errcode") != 0) {
            throw new WxRespException(result);
        }
        if (log.isInfoEnable()) {
            String info = "设置授权公众号["+authAppId+"]";
            if(info.equals("location_report")){
            	info += "地理位置上报选项成功,当前状态为: ";
            	if (optionValue.equals("0")) {
                    info += "无上报";
                } else if (optionValue.equals("1")) {
                    info += "进入会话时上报";
                } else {
                    info += "每5s上报";
                }
            } else if(info.equals("voice_recognize")){
            	info += "语音识别选项成功,当前状态为: ";
                info += (optionValue.equals("0")?"关闭":"开启");
            } else if(info.equals("voice_recognize")){
            	info += "多客服选项成功,当前状态为: ";
                info += (optionValue.equals("0")?"关闭":"开启");
            }   
            log.info("%s",info);
        }
    }

    /**
     * 得到微信返回的code之后，获取用户信息(openId)
     */
	@Override
	public WebAuthInfo getWebAuthInfo(String code) throws WxRespException {
		String url = String.format(WxApiUrl.OAUTH_TOKEN, mpAct.getAppId(), mpAct.getAppSecert(),code);
        String result = "";
        try {
            result = HttpRequest.get(url);
            log.info("获取网页授权公众号信息...\n请求地址:	%s\n 请求结果:	%s",url,result);
        } catch (IOException e) {
            log.error("换取授权公众号信息时出现异常!!!", e);
        }
        JSONObject jsonResult = JSON.parseObject(result);
        if (null != jsonResult.getInteger("errcode") && jsonResult.getInteger("errcode") != 0) {
            throw new WxRespException(result);
        }
        WebAuthInfo authInfo = JSON.parseObject(result, WebAuthInfo.class);
        return authInfo;
	}
	
}
